
#include "cycle.h"
#include "core.h"

static int cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2);
//static int init_zone_pool(cycle_t *cycle, shm_zone_t *shm_zone);

volatile cycle_t *g_cycle;
static event_t	cleaner_event;

/*
static int init_zone_pool(cycle_t *cycle, shm_zone_t *zn)
{
	char	*file = "xxxx.lock";
	slab_pool_t	*sp;

	sp	= (slab_pool_t*)zn->shm.addr;
	if (zn->shm.exists){
		if (sp == sp->addr)
			return 0;
		return -1;
	}

	sp->end	= zn->shm.addr + zn->shm.size;
	sp->min_shift	= 3;
	sp->addr	= zn->shm.addr;

	if (shmtx_create(&sp->mutex, &sp->lock, file) == -1)
		return -1;

	slab_init(sp);

	return 0;
}
*/

cycle_t *g_init_cycle(cycle_t *old_cycle)
{
	void	*rv;
	int	i, n;
	log_t	*log;
	pool_t	*pool;	
	cycle_t	*cycle;
	shm_zone_t	*shm_zone;
	list_part_t	*part;
	listening_t	*ls;

	log	= old_cycle->log;
	//申请cycle_pool_size大小空间，存放cycel_t对象的成员，成员中由于存在链表和数组可变，
	//所以这个空间也是可便的。只是第一次使用的时候申请大一点。
	pool	= create_pool(CYCLE_POOL_SIZE, log);	
	if (pool == NULL){
		fprintf(stderr, "create_pool() failed.\n");
		return NULL;
	}

	cycle = pcalloc(pool, sizeof(cycle_t));	//从pool中分配sizeof(cycle_t)大小空间,存放定长, 不定成数据指针头
	if (cycle == NULL){
		destroy_pool(pool);
		return NULL;
	}

	cycle->pool = pool;
	cycle->log = log;

	//共享内存，在一个链表中实现
	if (list_init(&cycle->shared_memory, pool, 1, sizeof(shm_zone_t)) == -1){
		destroy_pool(pool);
		return NULL;
	}

	//创建日志文件
	//cycle->log = log_create(cycle);
	
	//创建10个监听结构提，现在用tcp只用一个
	//以后添加时加上配置文件可以多个监听一起
	cycle->listening.elts = pcalloc(pool, sizeof(listening_t) * 10);
	if (cycle->listening.elts == NULL){
		destroy_pool(pool);
		return NULL;
	}

	cycle->listening.pool	= pool;
	cycle->listening.nelts = 0;
	cycle->listening.size = sizeof(listening_t);
	cycle->listening.nalloc = 10;

/*
	queue_init(&cycle->reuseable_connections_queue);


	//create shared memory
	part	= &cycle->shared_memory.part;
	shm_zone	= part->elts;
	for (i=0; ; i++){
		if (i >= part->nelts){
			if (part->next == NULL)
				break;
			part = part->next;
			shm_zone	= part->elts;
			i = 0;
		}
		
		if (shm_zone[i].shm.size = 0){
			goto failed;
		}

		if (shm_zone[i].init == NULL)
			continue;

		shm_zone[i].shm.log	= cycle->log;
		if (shm_alloc(&shm_zone[i].shm) == -1){
			goto failed;
		}		
		if (init_zone_pool(cycle, &shm_zone[i]) == -1){
			goto failed;
		}
		if (shm_zone[i].init(&shm_zone[i], NULL) == -1){
			goto failed;
		}
	}		
*/

	ls = cycle->listening.elts;
	for (i=0; i<cycle->listening.nelts; i++){
		ls[i].open = 1;
	}

	init_listening(cycle);	

	if (open_listening_sockets(cycle) == -1)
		goto failed;

	configure_listening_sockets(cycle);	
	

	if (!cleaner_event.timer_set){
		event_add_timer(&cleaner_event, 10000);
		cleaner_event.timer_set = 1;
	}


	return cycle;

failed:
	ls = cycle->listening.elts;
	for (i=0; i<cycle->listening.nelts; i++){
		if (ls[i].fd == -1 || !ls[i].open)
			continue;
		close(ls[i].fd);
	}

	destroy_pool(cycle->pool);
	
	return NULL;
}

